﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using Microsoft.SharePoint;
using System.Text;

namespace SPWeather365.SPWeather365WebPart
{
    [ToolboxItemAttribute(false)]
    public class SPWeather365WebPart : WebPart
    {
        private string _accountKey;
        private string _site;
        private int _siteId;

        /// <summary>
        /// Microsoft Azure Data Market Primary Account Key
        /// </summary>
        [Personalizable(PersonalizationScope.User)]
        public string AccountKey
        {
            get
            {
                return _accountKey;
            }

            set
            {
                _accountKey = value;
            }
        }

        /// <summary>
        /// Met Office SiteName.
        /// </summary>
        [Personalizable(PersonalizationScope.User)]
        public string SiteName
        {
            get
            {
                return _site;
            }

            set
            {
                _site = value;
            }
        }

        public override EditorPartCollection CreateEditorParts()
        {            
            var editors = new List<EditorPart>();
            var editorPart = new SPWeather365EditorPart();
            editorPart.ID = "SPWeatherEditorPart";
            editors.Add(editorPart);

            return new EditorPartCollection(editors);                        
        }       

        protected override void RenderContents(HtmlTextWriter writer)
        {
            StringBuilder js = new StringBuilder();

            js.AppendLine("var added = false");
            js.AppendLine("for (i = 0; (a = document.getElementsByTagName(\"link\")[i]); i++)");
            js.AppendLine("{");
            js.AppendLine("  if (a.getAttribute(\"rel\").indexOf(\"style\") != -1");
            js.AppendLine("      && a.getAttribute(\"href\").indexOf(\"spweather\") != -1)");
            js.AppendLine("  {");
            js.AppendLine("    added = true;");
            js.AppendLine("  }");
            js.AppendLine("}");
            js.AppendLine("if(!added)");
            js.AppendLine("{");
            js.AppendLine("  var head = document.getElementsByTagName(\"head\")[0];");
            js.AppendLine("  if(document.createStyleSheet)");
            js.AppendLine("  {");
            js.AppendLine("    document.createStyleSheet('" + SPContext.Current.Site.Url + "/style%20library/spweather/styles.css" + "');");
            js.AppendLine("  } else {");
            js.AppendLine("    var css = document.createElement('link');");
            js.AppendLine("    css.type = 'text/css';");
            js.AppendLine("    css.rel = 'stylesheet';");
            js.AppendLine("    css.href = '" + SPContext.Current.Site.Url + "/style library/spweather/styles.css" + "';");
            js.AppendLine("    head.appendChild(css);");
            js.AppendLine("  }");
            js.AppendLine("}");

            base.RenderContents(writer);

            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.WriteLine(js.ToString());
            writer.RenderEndTag();

            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.AddAttribute(HtmlTextWriterAttribute.Src, "//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.RenderEndTag();

            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.AddAttribute(HtmlTextWriterAttribute.Src, "//crypto-js.googlecode.com/files/2.5.3-crypto-min.js");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.RenderEndTag();

            js = new StringBuilder();
            js.AppendLine("Number.prototype.padLeft = function(width, char) {");
            js.AppendLine("    if (!char) {");
            js.AppendLine("        char = ' ';");
            js.AppendLine("    }");
            js.AppendLine("    if (('' + this).length >= width) {");
            js.AppendLine("        return '' + this;");
            js.AppendLine("    }");
            js.AppendLine("    else {");
            js.AppendLine("        return arguments.callee.call(");
            js.AppendLine("            char + this, ");
            js.AppendLine("            width, ");
            js.AppendLine("            char");
            js.AppendLine("        );");
            js.AppendLine("    }");
            js.AppendLine("};");
            js.AppendLine("var user = '2a49275f-ad43-459d-abe1-6476685da1a2';");
            js.AppendLine("var pwd = '" + _accountKey + "'");
            js.AppendLine("var description = new Array();");
            js.AppendLine("var today = new Date();");
            js.AppendLine("var month = (parseInt(today.getMonth())+1).padLeft(2,'0')");
            js.AppendLine("var day = parseInt(today.getDate()).padLeft(2,'0')");   
            js.AppendLine("$(document).ready(function () {");
            js.AppendLine("$.support.cors = true;");
            js.AppendLine("$.ajax({");
            js.AppendLine("    type: 'GET',");
            js.AppendLine("    beforeSend: function (xhr) {");
            js.AppendLine("        var bytes = Crypto.charenc.Binary.stringToBytes(user + ':' + pwd);");
            js.AppendLine("        var base64 = Crypto.util.bytesToBase64(bytes);");
            js.AppendLine("        xhr.setRequestHeader('Authorization', 'Basic ' + base64);");
            js.AppendLine("    },");
            js.AppendLine("    url: 'https://api.datamarket.azure.com/Data.ashx/DataGovUK/MetOfficeWeatherOpenData/SignificantWeather?$top=100&$format=json',");
            js.AppendLine("    dataType: 'json',");
            js.AppendLine("    success: function (data) {");
            js.AppendLine("        $.each(eval(data).d.results, function (i, item) {");
            js.AppendLine("            description[i] = item.Description;");
            js.AppendLine("        });");
            js.AppendLine("        dailyForecastUrl = 'https://api.datamarket.azure.com/Data.ashx/DataGovUK/MetOfficeWeatherOpenData/DailyForecast?$filter=ForecastSiteCode%20eq%203%20and%20Date%20eq%20datetime%27' + today.getYear() + '-' + month + '-' + day + 'T00%3a00%3a00%27&$top=1000&$format=json';");
            js.AppendLine("        $.ajax({");
            js.AppendLine("            type: 'GET',");
            js.AppendLine("            beforeSend: function (xhr) {");
            js.AppendLine("                var bytes = Crypto.charenc.Binary.stringToBytes(user + ':' + pwd);");
            js.AppendLine("                var base64 = Crypto.util.bytesToBase64(bytes);");
            js.AppendLine("                xhr.setRequestHeader('Authorization', 'Basic ' + base64);");
            js.AppendLine("            },");
            js.AppendLine("            url: dailyForecastUrl,");
            js.AppendLine("            dataType: 'json',");
            js.AppendLine("            success: function (data) {");
            js.AppendLine("                var results = eval(data);");
            js.AppendLine("                var count = 0;");
            js.AppendLine("                for(i=results.d.results.length - 5;i<results.d.results.length;i++){");
            js.AppendLine("                    dt = new Date(parseInt(results.d.results[i].Date.substring(6, 19)))");
            js.AppendLine("                    dt.setHours(dt.getHours() + results.d.results[i].TimeStep)");
            js.AppendLine("                    $('.Max' + count.toString()).html('Max: ' + results.d.results[i].FeelsLikeTemperatureDay.toString() + '\u00B0')");
            js.AppendLine("                    $('.Min' + count.toString()).html('Min: ' + results.d.results[i].FeelsLikeTemperatureNight.toString() + '\u00B0')");
            js.AppendLine("                    $('.Day' + count.toString()).html('')");
            js.AppendLine("                    significantWeather = description[results.d.results[i].SignificantWeatherIdDay + 1]");
            js.AppendLine("                    icon = significantWeather.replace(/ /g, '_').replace(/\\(/g, '').replace(/\\)/g, '')");
            js.AppendLine("                    $('.Day' + count.toString()).attr('class', icon)");
            js.AppendLine("                    count++;");
            js.AppendLine("                }");
            js.AppendLine("            },");
            js.AppendLine("            error: function (jqXHR, textStatus, errorThrown) {");
            js.AppendLine("                alert(errorThrown.message);");
            js.AppendLine("            }");
            js.AppendLine("        });");
            js.AppendLine("    },");
            js.AppendLine("    error: function (jqXHR, textStatus, errorThrown) {");
            js.AppendLine("        alert(errorThrown.message);");
            js.AppendLine("    }");
            js.AppendLine("});");
            js.AppendLine("});");

            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.WriteLine(js.ToString());
            writer.RenderEndTag();
        }

        protected override void CreateChildControls()
        {            
            Table table;
            TableRow tr;
            TableCell td;            

            if (!string.IsNullOrEmpty(_site))
            {
                _siteId = 0;
                int.TryParse(_site.Substring(_site.IndexOf("(") + 1, _site.IndexOf(")") - (_site.IndexOf("(") + 1)), out _siteId);
            }
            if (!string.IsNullOrEmpty(_accountKey))
                if (_siteId > 0)
                {                    
                    try
                    {                        
                        table = new Table() { CssClass = "spweather", CellPadding = 0, CellSpacing = 0 };
                        tr = new TableRow();
                        td = new TableCell();
                        TableHeaderRow trHeader = new TableHeaderRow();

                        for (int i=0; i<5;i++)
                        {
                            Table tableDay = new Table() { CellPadding = 0, CellSpacing = 0 };
                            TableRow trDay = new TableRow();
                            TableCell tdDay = new TableCell();
                            TableHeaderCell tdHeader = new TableHeaderCell()
                            {
                                ID = "Header" + i.ToString(),                                
                            };
                            if (i == 0)
                                tdHeader.Text = "Today";
                            else if (i == 1)
                                tdHeader.Text = "Tomorrow";
                            else
                                tdHeader.Text = DateTime.Now.AddDays(i).DayOfWeek.ToString();

                            tdHeader.Scope = TableHeaderScope.Column;
                            trHeader.Cells.Add(tdHeader);

                            tdDay = new TableCell() { CssClass="Day" + i.ToString(), ID = "Day" + i.ToString(), Text = "Day" + i.ToString() };
                            tdDay.RowSpan = 2;
                            Image imgDay = new Image() { CssClass = "ajaxLoader", ImageUrl = "/style%20library/spweather/images/ajax-loader.gif" };
                            tdDay.Controls.Add(imgDay);
                            trDay.Cells.Add(tdDay);

                            tdDay = new TableCell() { CssClass = "max Max" + i.ToString(), Text = "Max: " };
                            trDay.Cells.Add(tdDay);
                            tableDay.Rows.Add(trDay);

                            trDay = new TableRow();
                            tdDay = new TableCell() { CssClass = "min Min" + i.ToString(), Text = "Min: " };
                            trDay.Cells.Add(tdDay);
                            tableDay.Rows.Add(trDay);

                            tableDay.Rows.Add(trDay);

                            td = new TableCell();
                            td.Controls.Add(tableDay);
                            tr.Cells.Add(td);
                        }
                        table.Rows.Add(trHeader);
                        table.Rows.Add(tr);
                        this.Controls.Add(table);
                    }
                    catch (Exception ex)
                    {
                        this.Controls.Add(new Literal() { Text = "There was a problem accessing the Met Office data." });
                        return;
                    }
                }
                else
                {
                    this.Controls.Add(new Literal() { Text = "Please edit the web part and enter a location." });
                }
            else
            {
                this.Controls.Add(new Literal() { Text = "Please edit the web part and enter a Microsoft Azure Data Market Account Key." });
            }                    
        }
    }
}
